<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Nginx CORS 跨域配置完全指南</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .code-block {
            background: #1e293b;
            border-radius: 12px;
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
        }
        .text-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        pre code {
            color: #e2e8f0;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
        }
        .mermaid {
            display: flex;
            justify-content: center;
            margin: 2rem 0;
        }
        .floating-icon {
            animation: float 3s ease-in-out infinite;
        }
        @keyframes float {
            0%, 100% { transform: translateY(0px); }
            50% { transform: translateY(-10px); }
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-6">
        <div class="max-w-6xl mx-auto text-center">
            <div class="floating-icon inline-block mb-6">
                <i class="fas fa-globe text-6xl opacity-90"></i>
            </div>
            <h1 class="text-5xl md:text-6xl font-bold mb-6">Nginx CORS 跨域配置</h1>
            <p class="text-xl md:text-2xl opacity-90 max-w-3xl mx-auto leading-relaxed">
                掌握跨域资源共享的核心技术，让你的 Web 应用突破域名限制，实现无缝的资源访问
            </p>
        </div>
    </section>

    <!-- Main Content -->
    <main class="max-w-6xl mx-auto px-6 py-12">
        <!-- Introduction Card -->
        <div class="bg-white rounded-2xl shadow-xl p-8 mb-12 card-hover">
            <div class="flex items-start space-x-4">
                <div class="flex-shrink-0">
                    <div class="w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center">
                        <i class="fas fa-info-circle text-purple-600 text-2xl"></i>
                    </div>
                </div>
                <div class="flex-1">
                    <h2 class="text-2xl font-bold mb-3 text-gray-800">什么是 CORS？</h2>
                    <p class="text-gray-600 leading-relaxed text-lg">
                        在 Nginx 中实现跨域资源共享（CORS）涉及配置响应头以允许来自不同源的请求。CORS 是一种机制，它通过允许服务器在响应中添加特定的 HTTP 头来控制哪些域可以访问资源。
                    </p>
                </div>
            </div>
        </div>

        <!-- CORS Workflow Diagram -->
        <div class="bg-white rounded-2xl shadow-xl p-8 mb-12">
            <h3 class="text-2xl font-bold mb-6 text-center text-gray-800">CORS 工作流程图</h3>
            <div class="mermaid">
                graph LR
                    A[浏览器] -->|发起跨域请求| B[Nginx 服务器]
                    B -->|检查 Origin| C{是否允许?}
                    C -->|是| D[添加 CORS 头]
                    C -->|否| E[拒绝访问]
                    D --> F[返回响应]
                    E --> G[返回错误]
                    
                    style A fill:#667eea,stroke:#fff,stroke-width:2px,color:#fff
                    style B fill:#764ba2,stroke:#fff,stroke-width:2px,color:#fff
                    style D fill:#10b981,stroke:#fff,stroke-width:2px,color:#fff
                    style E fill:#ef4444,stroke:#fff,stroke-width:2px,color:#fff
            </div>
        </div>

        <!-- Configuration Sections -->
        <div class="space-y-12">
            <!-- Section 1 -->
            <section class="bg-white rounded-2xl shadow-xl overflow-hidden card-hover">
                <div class="bg-gradient-to-r from-purple-600 to-indigo-600 p-6">
                    <h3 class="text-2xl font-bold text-white flex items-center">
                        <i class="fas fa-cog mr-3"></i>
                        1. 配置 CORS 响应头
                    </h3>
                </div>
                <div class="p-8">
                    <p class="text-gray-600 mb-6 text-lg leading-relaxed">
                        要启用 CORS，需要在 Nginx 配置中添加适当的 HTTP 响应头。这些头部控制哪些域可以访问资源、哪些 HTTP 方法和请求头是被允许的。
                    </p>
                    <div class="code-block p-6 overflow-x-auto">
                        <pre><code>server {
    listen 80;
    server_name demo.com;

    location / {
        # 添加 CORS 响应头
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
        add_header Access-Control-Allow-Headers 'Authorization, Content-Type, X-Requested-With';

        # 处理预检请求
        if ($request_method = OPTIONS) {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
            add_header Access-Control-Allow-Headers 'Authorization, Content-Type, X-Requested-With';
            return 204;
        }

        # 代理到后端服务器
        proxy_pass http://backend;
    }
}</code></pre>
                    </div>
                </div>
            </section>

            <!-- Section 2 -->
            <section class="bg-white rounded-2xl shadow-xl overflow-hidden card-hover">
                <div class="bg-gradient-to-r from-indigo-600 to-purple-600 p-6">
                    <h3 class="text-2xl font-bold text-white flex items-center">
                        <i class="fas fa-paper-plane mr-3"></i>
                        2. 配置 CORS 预检请求（OPTIONS 请求）
                    </h3>
                </div>
                <div class="p-8">
                    <p class="text-gray-600 mb-6 text-lg leading-relaxed">
                        浏览器在某些情况下会发送一个 OPTIONS 请求（称为预检请求）来检查服务器是否允许实际请求。这种情况下，服务器需要响应预检请求并添加适当的 CORS 头。
                    </p>
                    <div class="code-block p-6 overflow-x-auto">
                        <pre><code>server {
    listen 80;
    server_name demo.com;

    location / {
        # 处理预检请求
        if ($request_method = OPTIONS) {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
            add_header Access-Control-Allow-Headers 'Authorization, Content-Type, X-Requested-With';
            return 204;
        }

        # 添加 CORS 响应头
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
        add_header Access-Control-Allow-Headers 'Authorization, Content-Type, X-Requested-With';

        # 代理到后端服务器
        proxy_pass http://backend;
    }
}</code></pre>
                    </div>
                </div>
            </section>

            <!-- Section 3 -->
            <section class="bg-white rounded-2xl shadow-xl overflow-hidden card-hover">
                <div class="bg-gradient-to-r from-purple-600 to-pink-600 p-6">
                    <h3 class="text-2xl font-bold text-white flex items-center">
                        <i class="fas fa-sync-alt mr-3"></i>
                        3. 动态设置 Access-Control-Allow-Origin 头
                    </h3>
                </div>
                <div class="p-8">
                    <p class="text-gray-600 mb-6 text-lg leading-relaxed">
                        如果需要限制特定的来源访问，应该动态设置 <code class="bg-gray-100 px-2 py-1 rounded text-purple-600">Access-Control-Allow-Origin</code> 头。可以使用 <code class="bg-gray-100 px-2 py-1 rounded text-purple-600">map</code> 指令来实现。
                    </p>
                    <div class="code-block p-6 overflow-x-auto">
                        <pre><code>http {
    map $http_origin $cors_origin {
        default "";
        "https://allowed-origin.com" $http_origin;
    }

    server {
        listen 80;
        server_name demo.com;

        location / {
            # 添加 CORS 响应头
            add_header Access-Control-Allow-Origin $cors_origin;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
            add_header Access-Control-Allow-Headers 'Authorization, Content-Type, X-Requested-With';

            # 处理预检请求
            if ($request_method = OPTIONS) {
                add_header Access-Control-Allow-Origin $cors_origin;
                add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
                add_header Access-Control-Allow-Headers 'Authorization, Content-Type, X-Requested-With';
                return 204;
            }

            # 代理到后端服务器
            proxy_pass http://backend;
        }
    }
}</code></pre>
                    </div>
                </div>
            </section>

            <!-- Additional Notes -->
            <section class="bg-white rounded-2xl shadow-xl overflow-hidden">
                <div class="bg-gradient-to-r from-pink-600 to-red-600 p-6">
                    <h3 class="text-2xl font-bold text-white flex items-center">
                        <i class="fas fa-exclamation-triangle mr-3"></i>
                        4. 其他注意事项
                    </h3>
                </div>
                <div class="p-8">
                    <div class="space-y-6">
                        <div class="flex items-start space-x-4">
                            <div class="flex-shrink-0">
                                <div class="w-10 h-10 bg-red-100 rounded-full flex items-center justify-center">
                                    <i class="fas fa-key text-red-600"></i>
                                </div>
                            </div>
                            <div class="flex-1">
                                <h4 class="font-bold text-lg mb-2">Access-Control-Allow-Credentials</h4>
                                <p class="text-gray-600 mb-3">
                                    如果请求需要发送凭证（如 Cookies），需要设置 <code class="bg-gray-100 px-2 py-1 rounded text-purple-600">Access-Control-Allow-Credentials</code> 头，并确保 <code class="bg-gray-100 px-2 py-1 rounded text-purple-600">Access-Control-Allow-Origin</code> 不使用通配符（*）。
                                </p>
                                <div class="code-block p-4">
                                    <pre><code>add_header Access-Control-Allow-Credentials true;</code></pre>
                                </div>
                            </div>
                        </div>

                        <div class="flex items-start space-x-4">
                            <div class="flex-shrink-0">
                                <div class="w-10 h-10 bg-red-100 rounded-full flex items-center justify-center">
                                    <i class="fas fa-eye text-red-600"></i>
                                </div>
                            </div>
                            <div class="flex-1">
                                <h4 class="font-bold text-lg mb-2">Access-Control-Expose-Headers</h4>
                                <p class="text-gray-600 mb-3">
                                    如果客户端需要访问特定的响应头，使用 <code class="bg-gray-100 px-2 py-1 rounded text-purple-600">Access-Control-Expose-Headers</code> 头来暴露这些头。
                                </p>
                                <div class="code-block p-4">
                                    <pre><code>add_header Access-Control-Expose-Headers 'X-My-Custom-Header';</code></pre>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </section>
        </div>

        <!-- Best Practices -->
        <div class="mt-12 bg-gradient-to-r from-green-